/*
 * wavetable.c
 *
 * 		Function for calculating wavetables for sine, saw-tooth
 * 		and square waveforms
 *
 *      Author: Colin
 */

#include <wavetable.h>

// arrays for waveforms
static int32_t sine[tableSize];
static int32_t saw[tableSize];
static int32_t square[tableSize];

/****************************************************************************
* DESCRIPTION: Initialise the wavetables
* RETURN:      pointer to wavetable array
*****************************************************************************/
int32_t* wavetable_init(int32_t waveform) {

	// init sine
	if(waveform == SINE) {

		// phase increment
		float phaseIncr = twoPI / tableSize;

		// phase
		float phase = 0;

		int32_t i;

		// populate table
		for(i = 0; i < tableSize; i++) {

			// calculating sine wave
			sine[i] = 340*sin(phase);

			// increment and test phase
			phase += phaseIncr;
			if (phase >= twoPI)
				phase -= twoPI;
			}

		// return pointer
		return &sine[0];
	}
	// init saw
	else if(waveform == SAW) {

		float phsIncr = twoPI / (tableSize);
		float phase = 0;
		float scale = 3.16;

		int32_t n;
		int32_t p;
		int32_t value;

		// calculate saw-tooth wave
		for (n = 0; n < tableSize; n++) {
		   value = 0;
		   for (p = 1; p <= 8; p++)
		      value += 512*(sin(phase*p) / p);
		   if ((phase += phsIncr) >= twoPI)
		      phase -= twoPI;
		   saw[n] = value / scale;
		}

		// return pointer
		return &saw[0];
	}
	// init square
	else if(waveform == SQUARE) {

		float phaseIncr = twoPI / (tableSize);
		float phase = 0;

		float midPoint = twoPI / 2;

		int32_t n;

		// calculate square wave
		for (n = 0; n < tableSize; n++) {
		    phase += phaseIncr;
		    if (phase >= twoPI)
		        phase -= twoPI; // or phase = 0;
		    if (phase >= midPoint)
		    	square[n] = -256;
		    else
		    	square[n] = 256;
		}

		// return pointer
		return &square[0];
	}

	return 0;
}
